class registers(object):

    def __init__(self, numRegisters=32, bits=32):
        self.numRegisters = numRegisters
        self.register = [0 for i in range(numRegisters)]
        self.bits = bits
        
    def initialize(self):
        self.register = [0 for i in range(self.numRegisters)]

    def setRegisters(self, array):
        assert len(array) == self.numRegisters
        self.register = array

    def __getitem__(self, regNum):
        return self.readRegister(regNum)

    def __setitem__(self, regNum, regValue):
        self.writeRegister(regNum, regValue)

    def readRegister(self, regNum):
        return self.register[regNum]

    def writeRegister(self, regNum, regValue):
        assert regValue >= 0 and regValue < (1 << self.bits)
        self.register[regNum] = regValue

    def returnSize(self):
        return self.numRegisters

    def printRegisters(self):
        for i in range(self.numRegisters):
            print(bin(self.register[i]))

    def getRegisterState(self):
        return self.register

class PipelineReg(object):
    def flush(self):
        self.signalAluOp=0
        self.signalAluSrc = 0
        self.signalRegDst=0
        self.signalRegWrite = 0
        self.signalBranch = 0
        self.signalBranchne = 0
        self.signalShift = 0
        self.signalSyscall = 0
        self.signalException = 0
        self.signalERET = 0
        self.signalUpperImmediate = 0
        self.signalMduOp = 0
        self.signalMemWrite = 0
        self.signalMemRead = 0
        self.signalMemToReg = 0
        
        
    def initialize(self):
        self.PCPlus4 = 0
        self.instruction = 0
        self.oppcode = 0
        self.regT = 0
        self.regD = 0
        self.regS = 0
        self.sa = 0
        self.readData1 = 0
        self.readData2 = 0
        self.immediateValue = 0
        
        ##signals from control unit
        self.signalAluOp=0
        self.signalAluSrc = 0
        self.signalRegDst=0
        self.signalRegWrite = 0
        self.signalBranch = 0
        self.signalBranchne = 0
        self.signalShift = 0
        self.signalSyscall = 0
        self.signalException = 0
        self.signalERET = 0
        self.signalUpperImmediate = 0
        self.signalMduOp = 0
        self.signalMemWrite = 0
        self.signalMemRead = 0
        self.signalMemToReg = 0
        self.isMduWrite = 0 ##user defined bit.
        self.PCBranchJump = 0
        self.signalDivideByZero = 0
        self.signalArithmeticOverflow = 0
        
        self.aluResult = 0
        self.mduHi = 0
        self.mduLo = 0
        self.zeroResult = 0
        self.writeRegister = 0
        self.memReadData = 0